package com.micro.utils;

import com.micro.entity.FileInfo;
import com.micro.entity.RequestHeader;
import com.micro.entity.TaskInfo;
import lombok.extern.slf4j.Slf4j;
import okhttp3.Response;
import org.apache.commons.lang3.StringUtils;
import org.junit.Test;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
 * @author dufen
 */
@Slf4j
public class ResolveUtil {
    public static boolean findTs(String str) {
        return (str.indexOf(".ts") > -1 || StringUtils.contains(str, "m4s")|| StringUtils.contains(str, ".jpg")) && !(StringUtils.contains(str, "EXT-X-KEY:METHOD") || StringUtils.contains(str, "IV="));
    }

    public static boolean findMethod(String str) {
        return str.indexOf("EXT-X-KEY:METHOD") > -1 && str.indexOf("URI=") > -1 && str.indexOf("IV=") > -1;
    }

    public static boolean findKey(String str) {
        return str.indexOf("EXT-X-KEY:METHOD") > -1 && str.indexOf("URI=") > -1;
    }

    public static List<FileInfo> resolveTypeI(String body) {
        String[] list = body.split("\n");
        List<String> m3u8List = new ArrayList<>();
        Collections.addAll(m3u8List, list);
        List<FileInfo> fileInfos = new ArrayList<>();
        final int[] count = {0};
        m3u8List.stream().filter(StringUtils::isNotBlank).filter(ResolveUtil::findTs).forEach(t -> {
            count[0]++;
            FileInfo fileInfo = new FileInfo();
            fileInfo.setNo(count[0]);
            fileInfo.setTempName(count[0] + ".temp");
            fileInfo.setTsUrl(t);
            fileInfos.add(fileInfo);

        });
        List<String> keyList = new ArrayList<>();
        m3u8List.stream().filter(StringUtils::isNotBlank).filter(ResolveUtil::findMethod).distinct().forEach(keyList::add);
        if (keyList.isEmpty()) {
            m3u8List.stream().filter(StringUtils::isNotBlank).filter(ResolveUtil::findKey).forEach(keyList::add);
        }
        if (keyList.size() > 0) {
            String[] strs = keyList.get(0).split(",");
            if (strs.length >= 3) {
                String[] methodStr = strs[0].split("=");
                String[] keyStr = strs[1].split("=\"");
                String[] ivStr = strs[2].split("=");
                fileInfos.stream().forEach(t -> {
                    t.setKey(keyStr.length > 1 ? keyStr[1].replace("\"", "") : "");
                    t.setMethod(methodStr.length > 1 ? methodStr[1] : "");
                    t.setIv(ivStr.length > 1 ? ivStr[1].replace("0x", "") : "");
                });
            } else if (strs.length == 2) {
                //#EXT-X-KEY:METHOD=AES-128,URI="https://ts.aa123bb.com/20210809/BtpRVIb9/1000kb/hls/key.key"
                String[] methodStr = strs[0].split("=");
                String[] keyStr = strs[1].split("=\"");
                fileInfos.stream().forEach(t -> {
                    t.setKey(keyStr.length > 1 ? keyStr[1].replace("\"", "") : "");
                    t.setMethod(methodStr.length > 1 ? methodStr[1] : "");
                });
            }
        }
        return fileInfos;
    }

    /**
     * @param taskInfo
     */
    public static void processTask(TaskInfo taskInfo) throws IOException {
        String url = taskInfo.getUrl();
        taskInfo.setOperation("解析中......");
        String content = getContent(taskInfo);
        if (StringUtils.isNotBlank(content)) {
            List<FileInfo> fileInfos = resolveTypeI(content);
            taskInfo.setFileInfos(fileInfos);
            taskInfo.setTotal(fileInfos.size());
            if (!(fileInfos==null || fileInfos.size()==0)) {
                if (!fileInfos.get(0).getTsUrl().contains("http")) {
                    Response response = null;
                    try {
                        response = HttpUtil.okHttpGet(getUrlPrefixA(url) + fileInfos.get(0).getTsUrl(), taskInfo.getRequestHeader());
                        //拼接请求查看是否成功
                        if (response.isSuccessful()) {
                            taskInfo.setBaseUrl(getUrlPrefixA(url));
                        } else {
                            response = HttpUtil.okHttpGet(getUrlPrefixB(url) + fileInfos.get(0).getTsUrl(), taskInfo.getRequestHeader());
                            if (response.isSuccessful()) {
                                taskInfo.setBaseUrl(getUrlPrefixB(url));
                            }
                        }
                    } catch (Exception e) {
                        try {
                            response = HttpUtil.okHttpGet(getUrlPrefixB(url) + fileInfos.get(0).getTsUrl(), taskInfo.getRequestHeader());
                            if (response.isSuccessful()) {
                                taskInfo.setBaseUrl(getUrlPrefixB(url));
                            }
                        } catch (IOException ex) {
                            ex.printStackTrace();
                        }
                    }
                }
            }
            if (StringUtils.isNotBlank(taskInfo.getBaseUrl())) {
                List<FileInfo> delfiles = new ArrayList<>();
                fileInfos.stream().forEach(fileInfo -> {
                    fileInfo.setTsUrl(StringUtils.contains(fileInfo.getTsUrl(), "http") ? fileInfo.getTsUrl() : taskInfo.getBaseUrl() + (StringUtils.indexOf(fileInfo.getTsUrl(), "/") == 0 ? StringUtils.substring(fileInfo.getTsUrl(), 1) : fileInfo.getTsUrl()));
                    if (StringUtils.isNotBlank(fileInfo.getKey())) {
                        fileInfo.setKey(StringUtils.contains(fileInfo.getKey(), "http") ? fileInfo.getKey() : taskInfo.getBaseUrl() + (StringUtils.indexOf(fileInfo.getKey(), "/") == 0 ? StringUtils.substring(fileInfo.getKey(), 1) : fileInfo.getKey()));
                    }
                    //排除存在第二key,暂定，因为有可能在前面
                    if (StringUtils.contains(fileInfo.getKey(), getUrlMiddle(fileInfo.getTsUrl())) == false && StringUtils.contains(fileInfo.getKey(), "http")) {
                        delfiles.add(fileInfo);
                    }
                });
                if (delfiles.size() != fileInfos.size()) {
                    delfiles.stream().forEach(fileInfos::remove);
                }
            }
        } else {
            taskInfo.setOperation("地址无效，解析失败");
            log.info("请求失败：{};", url);
        }
    }

    /**
     * 截取从0到最后一个斜杠的位置
     *
     * @param url
     * @return
     */
    public static String getUrlPrefixA(String url) {
        return StringUtils.substring(url, StringUtils.indexOf(url, "http"), StringUtils.lastIndexOf(url, "/") + 1);
    }

    /**
     * 截取双斜杠后第一个斜杠的位置
     *
     * @param url
     * @return
     */
    public static String getUrlPrefixB(String url) {
        return StringUtils.substring(url, 0, StringUtils.indexOf(StringUtils.substring(url, StringUtils.indexOf(url, "//") + 2), "/") + StringUtils.indexOf(url, "//") + 3);
    }

    public static boolean findM3u8(String content) {
        return StringUtils.contains(content, ".m3u8");
    }

    public static List<String> getM3u8(String content) {
        String[] strs = StringUtils.isNotBlank(content) ? content.split("\n") : new String[0];
        List<String> list = strs != null && strs.length > 0 ? new ArrayList<>(Arrays.asList(strs)) : new ArrayList<>();
        List<String> suffix = new ArrayList<>();
        list.stream().filter(s -> StringUtils.contains(s, ".m3u8")).forEach(suffix::add);
        return suffix;
    }

    public static String getContent(TaskInfo taskInfo) throws IOException {
        Response response = HttpUtil.okHttpGet(taskInfo.getUrl(), taskInfo.getRequestHeader());
        if (response != null && response.isSuccessful()) {
            String body = response.body().string();
            if (findM3u8(body)) {
                List<String> m3u8Url = getM3u8(body);
                String suffix = m3u8Url.size() == 1 ? m3u8Url.get(0) : m3u8Url.size() > 1 ? m3u8Url.get(m3u8Url.size() - 1) : "";
                //判断后缀链接有无http
                if (StringUtils.contains(suffix, "http") && StringUtils.indexOf(suffix, "http") == 0) {
                    return getContent(taskInfo);
                } else {
                    //https://cdn.605-zy.com/20210713/et72rrzy/
                    String prefix = getUrlPrefixA(taskInfo.getUrl());
                    String tempUrl = splicingUrl(prefix, suffix);
                    response = HttpUtil.okHttpGet(tempUrl, taskInfo.getRequestHeader());
                    //判断请求是否成功，成功则发送请求，否则执行其他逻辑
                    if (response != null && response.isSuccessful()) {
                        return response.body().string();
                    }
                    //https://cdn.605-zy.com/
                    prefix = getUrlPrefixB(taskInfo.getUrl());
                    tempUrl = splicingUrl(prefix, suffix);
                    response = HttpUtil.okHttpGet(tempUrl, taskInfo.getRequestHeader());
                    if (response != null && response.isSuccessful()) {
                        return response.body().string();
                    }

                }
            }
            taskInfo.setBaseUrl(StringUtils.substring(taskInfo.getUrl(), 0, StringUtils.lastIndexOf(taskInfo.getUrl(), "/") + 1));
            return body;
        }
        log.info("请求失败：{}", taskInfo.getUrl());
        taskInfo.setOperation("地址无效");
        return null;
    }

    public static String splicingUrl(String prefix, String suffix) {
        if (StringUtils.lastIndexOf(prefix, "/") == (StringUtils.length(prefix) - 1) || StringUtils.indexOf(suffix, "/") == 0) {
            return prefix + suffix;
        } else {
            return prefix + "/" + suffix;
        }
    }

    /**
     * 取链接中间位置
     *
     * @param url
     * @return
     */
    private static String getUrlMiddle(String url) {
        String path = StringUtils.substring(url, url.indexOf("//") + 2);
        return StringUtils.substring(path, StringUtils.indexOf(path, "/"), StringUtils.lastIndexOf(path, "/"));
    }

    @Test
    public void testSubUrl() {
        System.out.println(getUrlPrefixB("https://cdn.605-zy.com/20210713/et72rrzy/index.m3u8"));
        System.out.println(getUrlPrefixA("https://cdn.605-zy.com/20210713/et72rrzy/index.m3u8"));
        String url = "https://cdn.605-zy.com/20210713/et72rrzy/index.m3u8";
        String path = url.substring(url.indexOf("//") + 2);
        System.out.println(path.substring(path.indexOf("/"), path.lastIndexOf("/")));
        System.out.println(getUrlMiddle(url));
    }

    @Test
    public void test() throws IOException {
        String url = "https://vip5.3sybf.com/20210515/P0iHCC0w/2000kb/hls/index.m3u8";
        TaskInfo taskInfo = new TaskInfo();
        RequestHeader requestHeader = new RequestHeader.Build().build();
       // requestHeader .addHeader("referer","https://www.aiwuav.xyz").addHeader("origin","https://www.aiwuav.xyz");
        taskInfo.setRequestHeader(requestHeader);
        taskInfo.setUrl(url);
        processTask(taskInfo);
        System.out.println(taskInfo.getFileInfos().size());
    }
}
